// src/main/java/com/yourpackage/service/impl/OssServiceImpl.java
package com.reliable.service.oss.serviceimpl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.PutObjectRequest;
import com.reliable.framework.oss.properties.OssProperties;
import com.reliable.service.oss.service.OssService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.Base64;
import java.util.List;
import java.util.Random;

@Slf4j
@Service
public class OssServiceImpl implements OssService {

    @Autowired
    private OSS ossClient;


    @Autowired
    private OssProperties ossProperties;

    @Override
    public String uploadFile(MultipartFile file) throws IOException {
        return uploadFileInternal(file.getOriginalFilename(), file.getInputStream(), file.getSize());
    }

    @Override
    public String uploadBase64Image(String base64Data) throws IOException {
        if (base64Data == null || base64Data.trim().isEmpty()) {
            throw new IllegalArgumentException("Base64 数据不能为空");
        }

        try {
            // 1. 分离 Data URL 的元数据和实际数据
            String[] parts = base64Data.split(",", 2);
            String imageData = parts.length > 1 ? parts[1] : base64Data;

            // 2. 解码 Base64
            byte[] imageBytes = Base64.getDecoder().decode(imageData);

            // 3. 推断文件扩展名
            String fileExtension = ".jpg"; // 默认
            if (parts.length > 1) {
                String mimeType = parts[0];
                if (mimeType.contains("image/png")) {
                    fileExtension = ".png";
                } else if (mimeType.contains("image/gif")) {
                    fileExtension = ".gif";
                } else if (mimeType.contains("image/webp")) {
                    fileExtension = ".webp";
                }
                // 可根据需要添加更多类型
            }

            // 4. 生成唯一文件名
            String fileName = System.currentTimeMillis() + "_" + new Random().nextInt(10000) + fileExtension;

            // 5. 将字节数组包装成 InputStream 并上传
            ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
            return uploadFileInternal(fileName, inputStream, imageBytes.length);
        } catch (IllegalArgumentException e) {
            log.error("Base64 解码失败", e);
            throw new IOException("图片格式错误，无法解码", e);
        } catch (Exception e) {
            log.error("上传 Base64 图片失败", e);
            throw new IOException("图片上传失败: " + e.getMessage(), e);
        }
    }

    @Override
    public void deleteFiles(List<String> objectNames) {
        if (objectNames == null || objectNames.isEmpty()) {
            return;
        }
        try {
            for (String objectName : objectNames) {
                ossClient.deleteObject(ossProperties.getBucketName(), objectName);
                log.info("OSS 文件已删除: {}", objectName);
            }
        } catch (Exception e) {
            log.error("批量删除 OSS 文件失败", e);
            // 根据业务需求，可以选择抛出异常或记录日志
        }
    }

    @Override
    public String generatePresignedUrl(String objectName, long expiration) {
        try {
            java.util.Date expireDate = new java.util.Date(System.currentTimeMillis() + expiration);
            java.net.URL signedUrl = ossClient.generatePresignedUrl(ossProperties.getBucketName(), objectName, expireDate);
            return signedUrl.toString();
        } catch (Exception e) {
            log.error("生成签名 URL 失败", e);
            return null;
        }
    }

    /**
     * 上传文件的核心逻辑
     */
    private String uploadFileInternal(String originalFilename, java.io.InputStream inputStream, long size) throws IOException {
        try {
            // 1. 生成在 OSS 中的存储路径
            String fileHost = ossProperties.getFileHost();
            String extension = "";
            if (originalFilename != null && originalFilename.contains(".")) {
                extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            }
            String objectName = (fileHost.isEmpty() ? "" : fileHost + "/") + System.currentTimeMillis() + "_" + new Random().nextInt(1000) + extension;

            // 2. 创建上传请求
            PutObjectRequest request = new PutObjectRequest(ossProperties.getBucketName(), objectName, inputStream);

            // 3. 执行上传
            ossClient.putObject(request);

            // 4. 返回访问 URL
            String url = ossProperties.getDomain() + "/" + objectName;
            log.info("文件上传成功: {} -> {}", originalFilename, url);
            return url;
        } catch (Exception e) {
            log.error("OSS 上传文件失败", e);
            throw new IOException("文件上传到云端失败", e);
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (Exception e) {
                log.error("关闭 InputStream 失败", e);
            }
        }
    }


    @Override
    public String uploadFile(File file) throws IOException {
        if (file == null || !file.exists() || !file.isFile()) {
            throw new IllegalArgumentException("文件不存在或无效: " + (file != null ? file.getAbsolutePath() : "null"));
        }
        return uploadFileInternal(file.getName(), new java.io.FileInputStream(file), file.length());
    }
}